package com.groupbuying.settleproducer.service.impl;

import com.groupbuying.settleproducer.connector.FinancialFeign;
import com.groupbuying.settleproducer.connector.SysconfigFeign;
import com.groupbuying.settleproducer.constants.SettleUshopWithdrawalYsBalancePaymentEnumConstants;
import com.groupbuying.settleproducer.constants.SettleWithdrawalEnumConstants;
import com.groupbuying.settleproducer.constants.StoreFlowDescription;
import com.groupbuying.settleproducer.dao.SettleUshopIntegralPaymentDao;
import com.groupbuying.settleproducer.dao.SettleUshopWithdrawalDao;
import com.groupbuying.settleproducer.dao.SettleUshopWithdrawalYsBalancePaymentDao;
import com.groupbuying.settleproducer.domain.SettleUshopWithdrawalDO;
import com.groupbuying.settleproducer.domain.SettleUshopWithdrawalYsBalancePaymentDO;
import com.groupbuying.settleproducer.domain.SettleUshopWithdrawalYsIntegralPaymentDO;
import com.groupbuying.settleproducer.service.SettleUshopBalanceAndIntegralService;
import com.groupbuying.settleproducer.utils.DateUtils;
import com.groupbuying.settleproducer.utils.apiresult.ApiResult;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: WANGNING
 * @Email wyn20140226@aliyun.com
 * @Date: 2019/8/29 17:43
 * @Des 余额/积分代付业务接口
 */
@Service
public class SettleUshopBalanceAndIntegralServiceImpl implements SettleUshopBalanceAndIntegralService {
    public static final Logger logger = LoggerFactory.getLogger(SettleUshopBalanceAndIntegralServiceImpl.class);
    @Autowired
    private FinancialFeign financialFeign;
    @Autowired
    private SettleUshopWithdrawalYsBalancePaymentDao settleUshopWithdrawalYsBalancePaymentDao;
    @Autowired
    private SettleUshopWithdrawalDao settleUshopWithdrawalDao;
    @Autowired
    private SysconfigFeign sysconfigFeign;
    @Autowired
    private SettleUshopIntegralPaymentDao settleUshopIntegralPaymentDao;

    @Override
    public ApiResult balanceAndIntegral(Map<String, Object> map) {
        Map<String, Object> financialMap = new HashMap<>();
        /*获取参数调用金融中心*/
        logger.info("SettleUshopBalanceAndIntegralServiceImpl.balanceAndIntegral()-----余额/积分代付从商户中心获取到的map信息:" + map.toString());
        // 解析map参数---商户号（门店id）
        Object tempParam = map.get("storeUuid");
        String storeUuid = tempParam == null ? null : tempParam.toString();
        // 解析map参数---代付金额
        tempParam = map.get("balanceAmount");
        String balancePaymentAmountStr = tempParam == null ? null : tempParam.toString();
        BigDecimal balancePaymentAmount = new BigDecimal(balancePaymentAmountStr);
        // 解析map参数---代付总金额
        tempParam = map.get("totalAmount");
        String allPriceStr = tempParam == null ? null : tempParam.toString();
        BigDecimal totalAmount = new BigDecimal(allPriceStr);
        //获取代付id（从商户中心获取）
        tempParam = map.get("withdrawalId");
        String withdrawalId = tempParam == null ? null : tempParam.toString();
        // 解析map参数---订单说明
        tempParam = map.get("subject");
        String subject = tempParam == null ? null : tempParam.toString();
        //获取商户账户余额（从商户中心获取）
        tempParam = map.get("totalAcountAmount");
        String totalAcountAmount = tempParam == null ? null : tempParam.toString();
        /*-----------获取该商户的银行卡信息---------*/
        // 解析map参数---银行名称
        tempParam = map.get("bankName");
        String bankName = tempParam == null ? null : tempParam.toString();
        // 解析map参数---开户行所在城市
        tempParam = map.get("cityName");
        String bankCity = tempParam == null ? null : tempParam.toString();
        // 解析map参数---银行帐号
        tempParam = map.get("bankAccountNo");
        String bankAccountNo = tempParam == null ? null : tempParam.toString();
        // 解析map参数---银行帐号用户名
        tempParam = map.get("bankAccountName");
        String bankAccountName = tempParam == null ? null : tempParam.toString();
        // 解析map参数---收款方银行账户类型corporate :对公账户;personal:对私账户
        tempParam = map.get("bankAccountType");
        String bankAccountType = tempParam == null ? null : tempParam.toString();
        // 解析map参数---支持卡类型debit:借记卡;credit:信用卡 unit:单位结算卡
        tempParam = map.get("bankCardType");
        String bankCardType = tempParam == null ? null : tempParam.toString();
        tempParam = map.get("integralAmount");
        String integralAmountStr = tempParam == null ? null : tempParam.toString();
        //判断请求参数不为空
        if (StringUtils.isEmpty(balancePaymentAmountStr) || StringUtils.isEmpty(withdrawalId) || StringUtils.isEmpty(subject) || StringUtils.isEmpty(bankName) || StringUtils.isEmpty(bankCity) ||
                StringUtils.isEmpty(bankAccountNo) || StringUtils.isEmpty(bankAccountName) || StringUtils.isEmpty(bankAccountType) || StringUtils.isEmpty(bankCardType)|| StringUtils.isEmpty(totalAcountAmount)
        ) {
            logger.info("SettleUshopBalanceAndIntegralServiceImpl.balance()-----从store中心获取的数据可能存在空数据:" + map.toString());
            return ApiResult.failure(map.toString());
        }
        /*判断代付成分----余额/积分*/
        Boolean balanceStatus = false;
        Boolean integralStatus = false;
        int balanceRes = 0;
        int integralRes = 0;
        try {
            Map<String, Object> condMap = new HashedMap();
            condMap.put("withdrawalId", withdrawalId);
            condMap.put("splitState", SettleUshopWithdrawalYsBalancePaymentEnumConstants.ENUM_SPLITSTATE_SUC);
            if (!balancePaymentAmountStr.equalsIgnoreCase("0")) {
                /*判断代付成分----余额*/
                /*组装参数请求金融中心*/
                /*生成随机数4位*/
                String mathString = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
                String outTradeNo = DateUtils.format(new Date(), "yyyyMMdd") + storeUuid + mathString;
                financialMap.put("outTradeNo", outTradeNo);
                financialMap.put("balancePaymentAmount", balancePaymentAmountStr);
                financialMap.put("bankName", bankName);
                financialMap.put("subject", subject);
                financialMap.put("bankCity", bankCity);
                financialMap.put("bankAccountName", bankAccountName);
                financialMap.put("bankCardType", bankCardType);
                financialMap.put("bankAccountType", bankAccountType);
                financialMap.put("bankAccountNo", bankAccountNo);
                balanceStatus = financialFeign.balancePayment(financialMap);
                /*记录余额代付子表记录*/
                SettleUshopWithdrawalYsBalancePaymentDO settleUshopWithdrawalYsBalancePaymentDO = new SettleUshopWithdrawalYsBalancePaymentDO();
                settleUshopWithdrawalYsBalancePaymentDO.setGmtCreate(new Date());
                settleUshopWithdrawalYsBalancePaymentDO.setGmtModified(new Date());
                settleUshopWithdrawalYsBalancePaymentDO.setIsDelete(SettleUshopWithdrawalYsBalancePaymentEnumConstants.ENUM_ISDELETE_UNDEL);
                settleUshopWithdrawalYsBalancePaymentDO.setStoreId(storeUuid);
                settleUshopWithdrawalYsBalancePaymentDO.setOutTradeNo(outTradeNo);
                settleUshopWithdrawalYsBalancePaymentDO.setWithdrawalId(withdrawalId);
                settleUshopWithdrawalYsBalancePaymentDO.setWithdrawalPrice(totalAmount);
                settleUshopWithdrawalYsBalancePaymentDO.setSplitState(SettleUshopWithdrawalYsBalancePaymentEnumConstants.ENUM_SPLITSTATE_FAIL);
                balanceRes = settleUshopWithdrawalYsBalancePaymentDao.save(settleUshopWithdrawalYsBalancePaymentDO);
                if (balanceStatus) {
                    settleUshopWithdrawalYsBalancePaymentDao.updateStatus(condMap);
                }
            }
                if (!integralAmountStr.equalsIgnoreCase("0")) {
                logger.info("SettleUshopBalanceAndIntegralServiceImpl.integralAmount()----开始请求积分数据integral开始");
                /*判断代付成分----积分*/
                /*组装参数请求金融中心*/
                /*生成随机数4位*/
                String mathString = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
                String outTradeNo = DateUtils.format(new Date(), "yyyyMMdd") + storeUuid + mathString;
                financialMap.put("outTradeNo", outTradeNo);
                financialMap.put("integralAmount", integralAmountStr);
                financialMap.put("bankName", bankName);
                financialMap.put("subject", subject);
                financialMap.put("bankCity", bankCity);
                financialMap.put("bankAccountName", bankAccountName);
                financialMap.put("bankCardType", bankCardType);
                financialMap.put("bankAccountType", bankAccountType);
                financialMap.put("bankAccountNo", bankAccountNo);
                logger.info("SettleUshopBalanceAndIntegralServiceImpl.integralAmount()----开始请求金融中心积分数据integral开始:"+financialMap.toString());
                integralStatus = financialFeign.integralPayment(financialMap);
                logger.info("SettleUshopBalanceAndIntegralServiceImpl.integralAmount()----开始请求金融中心积分数据integral返回值为:"+integralStatus);
                /*记录积分代付子表记录*/
                SettleUshopWithdrawalYsIntegralPaymentDO settleUshopWithdrawalYsIntegralPaymentDO = new SettleUshopWithdrawalYsIntegralPaymentDO();
                settleUshopWithdrawalYsIntegralPaymentDO.setGmtCreate(new Date());
                settleUshopWithdrawalYsIntegralPaymentDO.setGmtModified(new Date());
                settleUshopWithdrawalYsIntegralPaymentDO.setIsDelete(SettleUshopWithdrawalYsBalancePaymentEnumConstants.ENUM_ISDELETE_UNDEL);
                settleUshopWithdrawalYsIntegralPaymentDO.setStoreId(storeUuid);
                settleUshopWithdrawalYsIntegralPaymentDO.setOutTradeNo(outTradeNo);
                settleUshopWithdrawalYsIntegralPaymentDO.setWithdrawalId(withdrawalId);
                settleUshopWithdrawalYsIntegralPaymentDO.setIntegralPrice(new BigDecimal(integralAmountStr));
                settleUshopWithdrawalYsIntegralPaymentDO.setSplitState(SettleUshopWithdrawalYsBalancePaymentEnumConstants.ENUM_SPLITSTATE_FAIL);
                integralRes = settleUshopIntegralPaymentDao.save(settleUshopWithdrawalYsIntegralPaymentDO);
                if (integralStatus) {
                    settleUshopWithdrawalYsBalancePaymentDao.updateStatus(condMap);
                }
            }
            /*记录提现总表*/
            SettleUshopWithdrawalDO settleWithdrawal = new SettleUshopWithdrawalDO();
            settleWithdrawal.setId(withdrawalId);
            settleWithdrawal.setCounterId(storeUuid);
            settleWithdrawal.setWithdrawalPrice(totalAmount);
            settleWithdrawal.setWithdrawalType(SettleWithdrawalEnumConstants.ENUM_WITHDRAWALTYPE_NOFIRST);
            String serviceFee = sysconfigFeign.getFeeCash();
            settleWithdrawal.setServiceFee(new BigDecimal(serviceFee));
            settleWithdrawal.setWithdrawalState(SettleWithdrawalEnumConstants.ENUM_WITHDRAWALSTATE_WAIT);
            settleWithdrawal.setTotalPrice(new BigDecimal(totalAcountAmount));
            settleWithdrawal.setGmtCreate(new Date());
            settleWithdrawal.setGmtModified(new Date());
            settleWithdrawal.setPaycompanyBalance(new BigDecimal("0.00"));
            settleWithdrawal.setIsDelete(SettleWithdrawalEnumConstants.ENUM_ISDELETE_UNDEL);
            settleUshopWithdrawalDao.save(settleWithdrawal);
            if ((balanceStatus && balanceRes > 0) || (integralStatus && integralRes > 0)) {
                /*更改余额记录子表为成功状态*/
                settleWithdrawal.setWithdrawalState(SettleWithdrawalEnumConstants.ENUM_WITHDRAWALSTATE_SUC);
                settleUshopWithdrawalDao.update(settleWithdrawal);
                logger.info("SettleUshopBalanceAndIntegralServiceImpl.balance()-----余额子表落库成功，返回提现总表记录");
                /*返回store中心数据*/
                Map<String, Object> withdrawalMap = notifyStoreAccount(storeUuid, allPriceStr, withdrawalId);
                /*描述*/
                withdrawalMap.put("description", String.format(StoreFlowDescription.WITHDRAWAL_SUCC, withdrawalId, allPriceStr));
                logger.error("SettleUshopBalanceAndIntegralServiceImpl.createFirstWithdrawal()-----通知商户中心更改资金变动情况，数据是：" + withdrawalMap.toString());
                return ApiResult.success(withdrawalMap);
            } else {
                logger.info("SettleUshopBalanceAndIntegralServiceImpl.balance()-----余额子表初始化失败");
                //通知商户同步余额状态
                Map<String, Object> withdrawalMap = notifyStoreAccount(storeUuid, allPriceStr, withdrawalId);
                /*描述*/
                withdrawalMap.put("description", String.format(StoreFlowDescription.WITHDRAWAL_FAIL, withdrawalId, allPriceStr));
                return ApiResult.failure(SettleWithdrawalEnumConstants.ENUM_WITHDRAWALCODE_FAIL, String.format(StoreFlowDescription.ENUM_NOTICESTORE_PLATFORM, allPriceStr), withdrawalMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ApiResult.failure();
    }

    //通知商户中心资金变动-----异常
    private Map<String, Object> notifyStoreAccount(String counterId, String allPrice, String withdrawalId) {
        //调用商户的feign接口通知商户同步余额状态
        Map<String, Object> withdrawalMap = new ConcurrentHashMap<>();
        /*商户提现金额*/
        withdrawalMap.put("operFreezeAmount", allPrice);
        /*支付单号*/
        withdrawalMap.put("orderNo", withdrawalId);
        /*商户账号*/
        withdrawalMap.put("storeUuid", counterId);
        /*业务类型*/
        withdrawalMap.put("businessType", SettleWithdrawalEnumConstants.ENUM_BUSINESS_WITHDRAWAL);
        /*金额标识--支出*/
        withdrawalMap.put("operType", SettleWithdrawalEnumConstants.ENUM_FREEZE_MONEY);
        /*商户会员号(待定--目前是商户号)*/
        withdrawalMap.put("customerUuid", counterId);
        return withdrawalMap;
    }

}
